/**************************************************************************//**
 * @item     CosyOS Kernel
 * @file     os_iss.c
 * @brief    中断异步服务
 * @author   迟凯峰
 * @version  V3.3.2
 * @date     2023.07.31
 ******************************************************************************/

#include "os_link.h"

/* 恢复任务 */
static void _resume_task_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspTaskNode task_node = ((tspISV_OpeTask)svs)->task_node;
	if(task_node->state & __SUSPENDED__)
	{
		task_node->state &= __RESUME__;
		if(!vScheduling_f)
		{
			if(task_node->state <= __FLOATING__ && task_node->TPL > vTASKING->TPL)
			{
				vScheduling_f = true;
			}
		}
	}
}

/* 挂起任务 */
static void _suspend_task_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspTaskNode task_node = ((tspISV_OpeTask)svs)->task_node;
	if(task_node->state < __SUSPENDED__)
	{
		task_node->state |= __SUSPENDED__;
		if(!vScheduling_f)
		{
			if(task_node == vTASKING)
			{
				vScheduling_f = true;
			}
		}
	}
}

/* 删除任务 */
static void _delete_task_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspTaskNode task_node = ((tspISV_OpeTask)svs)->task_node;
	task_node->state = __DELETED__;
	if(!vScheduling_f)
	{
		if(task_node == vTASKING)
		{
			vScheduling_f = true;
		}
	}
}

/* 设置任务优先级 */
static void _set_priority_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspTaskNode node_curr = ((tspISV_SetTPL)svs)->task_node;
	u8 tpl = ((tspISV_SetTPL)svs)->TPL;
	if(node_curr->TPL == tpl) return;
	node_curr->TPL = tpl;
	sSetPriority(node_curr);
	if(!vScheduling_f)
	{
		if(tpl > vTASKING->TPL && node_curr->state <= __FLOATING__)
		{
			vScheduling_f = true;
		}
	}
}

/* 设置延时 */
static void _set_delay_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspTaskNode task_node = ((tspISV_SetDly)svs)->task_node;
	if(task_node->state == __BLOCKED__ && task_node->blocktype == __DELAY__)
	{
		vDELAY_STMR[task_node->TID] = ((tspISV_SetDly)svs)->tc;
	}
}

/* 清除延时 */
static void _clr_delay_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspTaskNode task_node = ((tspISV_OpeTask)svs)->task_node;
	if(task_node->state == __BLOCKED__ && task_node->blocktype == __DELAY__)
	{
		vDELAY_STMR[task_node->TID] = 0;
		task_node->state = __READY__;
		if(!vScheduling_f)
		{
			if(task_node->TPL > vTASKING->TPL)
			{
				vScheduling_f = true;
			}
		}
	}
}

/* 定时中断 */
#if OS_TIMINTTOTAL
static void _timint_(void _XDATA_MEM_ *svs) __C51USING__
{
	vTIMINT_STMR[((tspISV_TimInt)svs)->tmid] =
	vTIMINT_BUFF[((tspISV_TimInt)svs)->tmid] = ((tspISV_TimInt)svs)->tcyc;
}
#else
#define _timint_ (tfpVP)NULL
#endif

/* 定时查询 */
#if OS_TIMQRYTOTAL
static void _timqry_(void _XDATA_MEM_ *svs) __C51USING__
{
	vTIMQRY_STMR[((tspISV_TimQry)svs)->tmid] =
	vTIMQRY_BUFF[((tspISV_TimQry)svs)->tmid] = ((tspISV_TimQry)svs)->tcyc;
}
#else
#define _timqry_ (tfpVP)NULL
#endif

/* 释放/上锁二值信号量 */
#if SYSCFG_BINARY == __ENABLED__
static void _write_bin_(void _XDATA_MEM_ *svs) __C51USING__
{
	*((tspISV_Bin)svs)->bin = ((tspISV_Bin)svs)->val;
}
#else
#define _write_bin_ (tfpVP)NULL
#endif

/* 释放计数信号量 */
#if SYSCFG_SEMAPHORE == __ENABLED__
static void _free_sem_(void _XDATA_MEM_ *svs) __C51USING__
{
	if(((tspISV_Sem)svs)->sem->counter < ((tspISV_Sem)svs)->sem->max)
	{
		((tspISV_Sem)svs)->sem->counter++;
	}
}
#else
#define _free_sem_ (tfpVP)NULL
#endif

/* 全局变量写访问 */
static void _write_var_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspVarNode_ISV var_node = ((tspISV_GVar)svs)->var_node;
	sWRITE_VAR_WRITE((tspVarNode)var_node);
	var_node->var_size
	? __memcpy(var_node->gvar, var_node->lvar, var_node->var_size)
	: __strcpy((char *)var_node->gvar, (char *)var_node->lvar);
	sWRITE_VAR_WRITE(NULL);
}

/* 全局变量自运算 */
static void _selfope_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspVarNode_ISV var_node = ((tspISV_SelfOpe)svs)->var_node;
	__memcpy(var_node->lvar, var_node->gvar, var_node->var_size);
	sWRITE_VAR_WRITE((tspVarNode)var_node);
	(*((tspISV_SelfOpe)svs)->fp)();
	sWRITE_VAR_WRITE(NULL);
}

/* 发送飞信 */
#if SYSCFG_FETION == __ENABLED__
static void _send_fetion_(void _XDATA_MEM_ *svs) __C51USING__
{
	*((tspISV_Fetion)svs)->tbox = ((tspISV_Fetion)svs)->fetion;
}
#else
#define _send_fetion_ (tfpVP)NULL
#endif

/* 发送邮件 */
#if SYSCFG_MAILBOX == __ENABLED__
static void _send_mail_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspMbxNode_ISV mbx_node = ((tspISV_Mbx)svs)->mbx_node;
	#if SYSCFG_INTRECVMAIL == 1
	mbx_node->lnmf = true;
	#endif
	sWRITE_MBX_WRITE((tspMbxNode)mbx_node);
	__memcpy(mbx_node->gmbx, mbx_node->lmbx, mbx_node->mbx_size);
	sWRITE_MBX_WRITE(NULL);
	#if SYSCFG_INTRECVMAIL == 0
	*mbx_node->gnmf = true;
	#elif SYSCFG_INTRECVMAIL == 1
	*mbx_node->gnmf = mbx_node->lnmf;
	#endif
}
#else
#define _send_mail_ (tfpVP)NULL
#endif

/* 发送消息 */
#if SYSCFG_MSGQUEUE == __ENABLED__
static void _send_msg_(void _XDATA_MEM_ *svs) __C51USING__
{
	tspMsgQueue msg_queue = ((tspISV_Msg)svs)->msg_queue;
	msg_queue->mutex = false;
	if(msg_queue->counter == msg_queue->len)
	{
		msg_queue->mutex = true;
		#if SYSCFG_DEBUGGING == __ENABLED__
		vAlarm.overflow_msgqueue = true;
		#endif
		return;
	}
	if(msg_queue->type == __DYNAMIC__)
	{
		tspMsgNode msg_node = NULL;
		msg_node = (tspMsgNode)__malloc(sizeof(tsMsgNode));
		if(msg_node == NULL)
		{
			msg_queue->mutex = true;
			#if SYSCFG_DEBUGGING == __ENABLED__
			vFault.mallocfail_msgnode = true;
			#endif
			return;
		}
		sSendMsg_Dynamic(((tspISV_Msg)svs)->msg);
	}
	else
	{
		sSendMsg_Static(((tspISV_Msg)svs)->msg);
	}
	msg_queue->mutex = true;
}
#else
#define _send_msg_ (tfpVP)NULL
#endif

/* 写标志组 */
#if SYSCFG_FLAGGROUP == __ENABLED__
static void _write_flaggrp_(void _XDATA_MEM_ *svs) __C51USING__
{
	switch(((tspISV_GRP)svs)->size)
	{
		case +1: *(u8  *)((tspISV_GRP)svs)->group |= ((tspISV_GRP)svs)->value; break;
		case +2: *(u16 *)((tspISV_GRP)svs)->group |= ((tspISV_GRP)svs)->value; break;
		case +4: *(u32 *)((tspISV_GRP)svs)->group |= ((tspISV_GRP)svs)->value; break;
		case -1: *(u8  *)((tspISV_GRP)svs)->group &=~((tspISV_GRP)svs)->value; break;
		case -2: *(u16 *)((tspISV_GRP)svs)->group &=~((tspISV_GRP)svs)->value; break;
		case -4: *(u32 *)((tspISV_GRP)svs)->group &=~((tspISV_GRP)svs)->value; break;
	}
}
#else
#define _write_flaggrp_ (tfpVP)NULL
#endif

typedef void (_CODE_MEM_ *tfpVP)(void _XDATA_MEM_ *);
void (_CODE_MEM_ * const _CONST_MEM_ vISV_Handler[__SVID_END__])(void _XDATA_MEM_ *) =
{
	_resume_task_,
	_suspend_task_,
	_delete_task_,
	_set_priority_,
	_set_delay_,
	_clr_delay_,
	_timint_,
	_timqry_,
	_write_bin_,
	_free_sem_,
	_write_var_,
	_selfope_,
	_send_fetion_,
	_send_mail_,
	_send_msg_,
	_write_flaggrp_
};
